Centroid Based Clustering

No Supervisado - Práctica

Primavera 2022

Vamos a utilizar la libreria nativa de R para k-means. Probaremos el algoritmo en ejemplos donde podamos explorar visualmente los resultados.


Al final propongo algunos ejercicios, idealmente para hacer durante la clase, en caso de no llegar quedan para practicar.

KMEANS

Librería nativa de R

Toy Example

Consideremos:

\[ X \sim N(\mu_1, \Sigma) \ \mbox{ y } \ Y \sim N(\mu_2, \Sigma), \] Parámetros:

  • \(\mu_1=(2,2)\)
  • \(\mu_2 = c(-1,-1)\)
  • \(\Sigma = \begin{pmatrix} 1 & 0 \\ 0 & 1 \end{pmatrix} = I_2\)

Toy Example

library(mvtnorm)

n = 50  # tamaño muestral para cada distribución
mu1 = c(2,2); mu2 = c(-1,-1) # medias
sigma = rbind(c(1,0),c(0,1)) # covarianza

X = rmvnorm(n, mu1, sigma)
Y = rmvnorm(n, mu2, sigma)

labs = c(rep(1,n), rep(2,n))
Z = rbind(X,Y)

Toy Example: kmeans

# Usamos la implentación kmeans nativa de R
k_means = kmeans(x=Z, centers=2, iter.max=10, nstart=2)

# Centros
k_means$centers
       [,1]      [,2]
1 -1.188200 -1.348810
2  1.794416  1.808978
# Etiquetas dadas por el algoritmo
k_means$cluster
  [1] 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
 [38] 2 2 2 2 2 2 2 2 2 2 1 2 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
 [75] 2 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2
# Cantidad de veces que se tuvo que correr
k_means$iter
[1] 1

Toy Example: kmeans

# Suma de cuadrados
k_means$totss
[1] 638.4786
# Varianza intra-cluster
k_means$tot.withinss
[1] 166.9766
# Varianza del cluster
k_means$withinss
[1]  63.22849 103.74816
# Varianza entre clusters
k_means$betweenss
[1] 471.502

Toy Example: kmeans

Toy Example: kmeans

Ejercicios:


1- Probar el algoritmo cambiando las normales por distribuciones t-bivariadas.

2- Modificando las matrices de covarianza encontrar un conjunto de datos que logre un mal desempeño del algoritmo. Intentar con una configuración de tres normales bivariadas.

3- ¿Es posible que algunos valores atípicos pueden quebrar el algoritmo? Probar agregando algunos outliers al conjunto de datos que usamos al comienzo.

4- Programar el algoritmo de kmeans y comparar con la implementación estándar.

SEGMENTACIÓN

Ejemplo en imágenes

Segmentación

Segmentación

Una imagen es un conjunto de píxeles, cada pixel se entiende como:

  • Un punto de 3 coordenadas si utilizamos escala de grises.
  • Un punto de 5 coordenadas si usamos colores (RGB).

\[ pixel = (x,y,R,G,B) \]

Segmentación

\[ pixel = (x,y,R,G,B) \] - x: coordenada ancho. - y: coordenada altura. - R: intesidad del color rojo representado en el intervalo [0, 1]; R = 0 implica que el pixel no posee rojo. - G: intesidad del color verde (idem rojo). - B: intesidad del color azul (idem rojo).

Segmetación


library(jpeg)
library(ggplot2)
library(gridExtra)
library(repr)

img = readJPEG("/home/lucas/no-supervisado/practicas_new/centroid_based/costa.jpeg") # img es una array de tres dimensiones 524x700x3
img_dim = dim(img)
img_dim
[1] 524 700   3

Segmetación


# Asignamos cada canal RGB a un dataframe
img_rgb = data.frame(
x = rep(1:img_dim[2], each = img_dim[1]), # coordenada x (width)
y = rep(img_dim[1]:1, img_dim[2]), # coordenada y (heigth)
R = as.vector(img[,,1]), # valor rojo
G = as.vector(img[,,2]), # valor verde
B = as.vector(img[,,3]) # valor azul
)
head(img_rgb)
  x   y         R         G         B
1 1 524 0.6588235 0.6431373 0.6470588
2 1 523 0.9137255 0.9058824 0.9098039
3 1 522 0.9411765 0.9411765 0.9411765
4 1 521 0.8980392 0.9137255 0.9098039
5 1 520 0.8392157 0.8627451 0.8549020
6 1 519 0.6313725 0.6666667 0.6549020

Segmentación


# Usamos kmeans sobre los colores para segmentar
k = 2
k_means <- kmeans(img_rgb[, c("R", "G", "B")], centers = k, nstart=2)
k_means$centers
          R         G         B
1 0.5257584 0.8034208 0.7486003
2 0.3239723 0.3854687 0.1750224


# Asigno a cada pixel el color del centro correspondiente a cada cluster
colores_centrales = rgb(k_means$centers[k_means$cluster,])
colores_centrales[1:5]
[1] "#86CDBF" "#86CDBF" "#86CDBF" "#86CDBF" "#86CDBF"

Segmentación

Ejercicios


1- Incrementar la cantidad de grupos y describir qué sucede con la imagen segmentada. ¿Cuántos grupos parecen razonables?¿Por qué?


2- Aplicar esto mismo a las imágenes que se encuentran en los archivos:

  • manos.png
  • 4.png
  • lobo.jpeg

¿Funciona igual en todas las imágenes? Discutir los resultados que se vayan obteniendo.